package org.jslaughter.component.stats;

import org.jslaughter.component.ai.BehaviourImpl;
import org.jslaughter.event.eventtype.DamageEvent;
import org.jslaughter.event.eventtype.DamageEvent.DAMAGE_TYPE;
import org.nvframe.component.AbstractComponent;
import org.nvframe.component.ai.Behaviour.BEHAVIOUR_TYPE;
import org.nvframe.component.physics.state.PhysicsPosition;
import org.nvframe.entity.Entity;
import org.nvframe.event.EventService;
import org.nvframe.event.eventtype.CollisionEvent;
import org.nvframe.event.eventtype.CollisionListener;
import org.nvframe.event.eventtype.UpdateEvent;
import org.nvframe.event.eventtype.UpdateListener;
import org.nvframe.util.NVMathUtils;
import org.nvframe.util.settings.SettingsObj;

/**
 * 
 * @author Nik Van Looy
 */
public class DamageOnCollision extends AbstractComponent implements CollisionListener, UpdateListener {
	
	protected int minDamagePoints;
	protected int maxDamagePoints;
	protected boolean removeOnCollision;
	
	private DAMAGE_TYPE damageType;

	public DamageOnCollision(String id, Entity owner, SettingsObj settings) {
		super(id, owner);
		
		minDamagePoints = settings.getInt("minDamagePoints", 0);
		maxDamagePoints = settings.getInt("maxDamagePoints", 0);
		removeOnCollision = settings.getBoolean("removeOnCollision", false);

		damageType = DAMAGE_TYPE.valueOf(settings.getString("damageType", DAMAGE_TYPE.COLLISION.toString()));
		
		EventService.getInstance().addEventListener(this);
	}
	
	@Override
	public void onCollision(CollisionEvent event) {
		Entity receiver;
		
		// determine the receiver for the damage
		if(event.getEntity1() == owner)
			receiver = event.getEntity2();
		else
			receiver = event.getEntity1();
		
		if(!owner.isEnabled() || !receiver.isEnabled())
			return;
		
		BehaviourImpl behaviour = (BehaviourImpl) owner.getComponent(BehaviourImpl.class);
		
		// check if we can do damage to the receiver (has health, doesn't block attacktype)
		if(!behaviour.canDoDamageTo(receiver, damageType))
			return;

		// aggressive towards receiver?
		if(behaviour.getBehaviourTowards(receiver) == BEHAVIOUR_TYPE.FRIENDLY)
			return;

		PhysicsPosition positionComp = (PhysicsPosition) owner.getComponent(PhysicsPosition.class);
		float hitDirection = (float) Math.toDegrees(NVMathUtils.calculateDirectionRad(owner, receiver));
		
		EventService.getInstance().fireEvent(new DamageEvent(owner, 
				receiver,
				NVMathUtils.getRandomNumberBetween(minDamagePoints, maxDamagePoints),
				damageType,
				hitDirection));
		
		if(positionComp.isBullet() || removeOnCollision) {
			PhysicsPosition receiverPos = (PhysicsPosition) receiver.getComponent(PhysicsPosition.class);
			
			// dont stop bullets on sensors (eg pickups)
			if(receiverPos != null && !receiverPos.isSensor())
				owner.removed();
		}
	}

	@Override
	public void onUpdate(UpdateEvent event) {
		
	}

}
